"""
Brilliant Hunger Games

Enrico Tanuwidjaja

The key to winning this game is to have as many people to be willing to hunt
with me, since I will receive 3 foods from each person who does that. Now,
how do I make people hunt with me? It really depends on how others think.
The only input for them that can encourage them to differentiate
me is my reputation. As for the other inputs (m, round number, etc.), it
will impact everyone equally. The only thing that I can change is my reputation,
and it might be the only thing that can encourage them to hunt with me. 
Therefore, I decide to play with my reputation.

Here is my strategy:
1. Keep hunting for the first few rounds, so that my reputation will be 1.
2. After that, keep slacking so that my reputation will drop from 1 to 0.5
(I decided to stop at 0.5 because I don't think below that point is good, and
getting reputation to go up is hard). At this point, I record what the result
of each round. I will have the record of what happens on every reputation between
0.5 and 1 (and I also consider the cost of keeping this reputation, which is the
percentage I need to hunt). This way I can predict how people are treating me if 
I'm in that reputation. Then I can decide what reputation can give me the best result.
3. After I find the best reputation to play with, I aim for that reputation, 
and keep that reputation.
4. When food drops low, I go into desperate mode, and I will keep slacking.
This will increase the duration of my survival.


I do not care who I want to hunt with. I do not care about their reputations. My
goal is only to make them hunt with me. So, I choose randomly with whom I want to hunt
and with whom I want to slack. (Of course, if all people think like this, reputation
no longer useful, and my whole strategy won't work. I'm assuming reputation matters).

I understand that the "optimal reputation" might change in the middle of the game,
since it depends on others. It might change when many people die, changing the
atmosphere of the game. However, I do not create the logic to handle this, since
it would be complicated and prone to error. So, I predict that optimal reputation 
in the beginning, and stay there forever.
"""

WARM_UP = 15
MAX_REP = 0.99

target_rep = 1.0
dict = {}
mode = 0
last_rep = 0.0
target_hunt = 0


def hunt_choices(round_number, current_food, current_reputation, m,  player_reputations):

    nHunt = 0
    nSlack = 0

    global target_rep, dict, mode, last_rep, target_hunt

    # 1. Keep hunting
    if round_number <= WARM_UP:
        hunt_decisions = ['h' for x in player_reputations]
        return hunt_decisions
    
    # 2. Keep slacking
    elif round_number <= 2 * WARM_UP:
        mode = 1
        last_rep = current_reputation
        hunt_decisions = ['s' for x in player_reputations]
        return hunt_decisions
    
    else:
        # 3. Find the best reputation to be in
        if mode == 1:
            mode = 2
            
            keys = sorted(dict.keys())
            dict2 = dict.copy()

            for i in range(len(keys)):
                total = 0
                cnt = 0
                if i > 0:
                    total += dict[keys[i-1]]
                    cnt += 1
                total += dict[keys[i]]
                cnt += 1
                if i < len(keys) - 1:
                    total += dict[keys[i+1]]
                    cnt += 1
        
                dict2[keys[i]] = float(total) / cnt
            
            ls = dict2.values()
            mx = max(ls)
            
            for k in dict2.keys():
                if dict2[k] == mx:
                    target_rep = k
            
            # number of rounds to keep hunting
            if target_rep > MAX_REP:
                target_rep = MAX_REP
            target_hunt = (2 * WARM_UP * target_rep - WARM_UP)/(1 - target_rep)
            target_hunt = int(round(target_hunt))
            
            #for k in sorted(dict.keys()):
            #    print "%f: %d || %d" % (k, dict[k], dict2[k])
                
            #print(">>>>>>>>>>>> Target rep = %f. target_hunt = %d" % (target_rep, target_hunt))
        
        # Keep hunting until reaching that optimal reputation            
        if mode == 2:
            target_hunt -= 1
            hunt_decisions = ['h' for x in player_reputations]
            if target_hunt <= 0:
                mode = 3
        
        # Keep that optimal reputation
        elif mode == 3:
            players = len(player_reputations)
            nHunt = int(round(target_rep * players))
            nSlack = players - nHunt
            
            hunt_decisions = []
            for i in range(nHunt):
                hunt_decisions.append('h')
            for i in range(nSlack):
                hunt_decisions.append('s')

    # Desperate mode, slack all the way
    if nHunt * 3 + nSlack * 2 > current_food:
       hunt_decisions = ['s' for x in player_reputations]
    
    return hunt_decisions;

def hunt_outcomes(food_earnings):
    
    global target_rep, dict, mode, last_rep
    
    if (mode == 1):
        res = total_earn = sum(food_earnings)
        # restore to original (undo the cost of slacking)
        players = len(food_earnings)
        res += 2 * players
        # simulate earning based on reputation
        nHunt = int(last_rep * players)
        nSlack = players - nHunt
        res = res - 3 * nHunt - 2 * nSlack
        
        #print "Total earnings = %d, Simulated earning = %d (Rep: %f, H/S: %d/%d)" % (total_earn, res, last_rep, nHunt, nSlack)
        
        # Record the result of this reputation
        dict[last_rep] = res

def round_end(award, m, number_hunters):

    pass